package sk.fei.vrml.vrmlio;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedList;

import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;
import javax.swing.tree.DefaultMutableTreeNode;

import sk.fei.vrml.gui.MainFrame;
import sk.fei.vrml.jogl.VrmlModel;
import sk.fei.vrml.main.Constants;
import sk.fei.vrml.objects.ImageTextureObject;
import sk.fei.vrml.objects.MaterialObject;
import sk.fei.vrml.objects.PixelTextureObject;
import sk.fei.vrml.objects.TextureObject;
import sk.fei.vrml.objects.TextureTransformObject;
import sk.fei.vrml.objects.VrmlAppearance;
import sk.fei.vrml.objects.VrmlBackground;
import sk.fei.vrml.objects.VrmlBox;
import sk.fei.vrml.objects.VrmlCone;
import sk.fei.vrml.objects.VrmlCylinder;
import sk.fei.vrml.objects.VrmlObject;
import sk.fei.vrml.objects.VrmlShape;
import sk.fei.vrml.objects.VrmlSphere;
import sk.fei.vrml.objects.VrmlTransform;
import sk.fei.vrml.objects.VrmlViewPoint;
import cv97.SceneGraph;
import cv97.field.MFColor;
import cv97.field.MFFloat;
import cv97.field.SFRotation;
import cv97.node.AppearanceNode;
import cv97.node.BackgroundNode;
import cv97.node.BoxNode;
import cv97.node.ConeNode;
import cv97.node.CylinderNode;
import cv97.node.GeometryNode;
import cv97.node.ImageTextureNode;
import cv97.node.MaterialNode;
import cv97.node.Node;
import cv97.node.PixelTextureNode;
import cv97.node.ShapeNode;
import cv97.node.SphereNode;
import cv97.node.TextureNode;
import cv97.node.TextureTransformNode;
import cv97.node.TransformNode;
import cv97.node.ViewpointNode;

// Portions of this software is based in part on the CyberVRML97 package written by Satoshi Konno

public class VrmlIO {

	private String lastDirectory;
	private LinkedList<VrmlObject> modelComponents;
	private MainFrame window;
	private SceneGraph sg;
	private boolean backgroundProcessed = false;
	private VrmlModel activeModel;
	private String fileName;

	public VrmlIO(LinkedList<VrmlObject> modelComponents, MainFrame window) {
		this.window = window;
		this.modelComponents = modelComponents;
		this.activeModel = this.window.listener.getActivModel();
	}

	/**
	 * Function exports VRML model to *.wrl file
	 */
	public void exportToFile() {

		fileName = showFileDialog(true);

		backgroundProcessed = false;

		// actualize model
		this.activeModel = this.window.listener.getActivModel();

		// continue only if user selected file
		if (fileName != null) {

			sg = new SceneGraph();

			// no changes after save
			this.activeModel.resetModelChanged();

			// BACKGROUND
			if (activeModel.isBackground() && backgroundProcessed == false) {

				backgroundProcessed = true;

				BackgroundNode backgroundNode = new BackgroundNode();
				VrmlBackground background = activeModel.getModelBackground();

				// sky angles
				if (background.getSkyAngles() != null) {
					for (int i = 0; i < background.getSkyAngles().length; i++) {
						backgroundNode
								.addSkyAngle(background.getSkyAngles()[i]);
					}
				}

				// sky colors
				if (background.getSkyColors() != null) {
					for (int i = 0; i < background.getSkyColors().length; i++) {
						backgroundNode
								.addSkyColor(background.getSkyColors()[i]);
					}
				}

				// ground angles
				if (background.getGroundAngles() != null) {
					for (int i = 0; i < background.getGroundAngles().length; i++) {
						backgroundNode.addGroundAngle(background
								.getGroundAngles()[i]);
					}
				}

				// ground colors
				if (background.getGroundColors() != null) {
					for (int i = 0; i < background.getGroundColors().length; i++) {
						backgroundNode.addGroundColor(background
								.getGroundColors()[i]);
					}
				}

				sg.addNode(backgroundNode);
			}

			// ALL OTHER OBJECT FROM OBJECT TREE
			for (VrmlObject obj : modelComponents) {
				exploreNodeExport(obj, null);
			}

			// save model to file
			sg.save(fileName);
		}

	}

	/**
	 * 
	 * Function recursively explore VRML node tree for export purpose
	 * 
	 * @param obj
	 *            is currently exploring object
	 * @param parentNode
	 *            is parent node (if specified)
	 */
	void exploreNodeExport(VrmlObject obj, Node parentNode) {
		// TRANSFORMATION //
		if (obj.getObjectType().equals(Constants.Transform)) {

			VrmlTransform trans = (VrmlTransform) obj;
			TransformNode transformNode = new TransformNode();

			// rotation
			transformNode.setRotation(1, 0, 0, trans.getRotationX());
			transformNode.setRotation(0, 1, 0, trans.getRotationY());
			transformNode.setRotation(0, 0, 1, trans.getRotationZ());

			// translation
			transformNode.setTranslation(trans.getTranslation());

			// scale
			transformNode.setScale(trans.getScale());

			// scaleOrientation
			transformNode.setScaleOrientation(trans.getScaleOrientation());

			// center
			transformNode.setCenter(trans.getCenter());
			
			// bboxCenter (not in model)
			transformNode.setBoundingBoxCenter(trans.getBboxCenter());

			// bboxSize (not in model)
			transformNode.setBoundingBoxSize(trans.getBboxSize());

			// name
			if (trans.getName() != null) {
				transformNode.setName(trans.getName());
			}

			// children
			LinkedList<VrmlObject> children = trans.getChildren();
			for (VrmlObject child : children) {
				exploreNodeExport(child, transformNode);
			}

			// if parent it's specified, add node to it, else add it to main
			// scene graph
			if (parentNode == null) {
				sg.addNode(transformNode);
			} else {
				// TODO add to the tree
				parentNode.addChildNode(transformNode);
			}

			// SHAPE //
		} else if (obj.getObjectType().equals(Constants.Shape)) {

			VrmlShape shape = (VrmlShape) obj;
			ShapeNode shapeNode = new ShapeNode();

			// shape name 
			if (shape.getName() != null) {
				shapeNode.setName(shape.getName());
			}

			// GEOMETRY //
			VrmlObject geometry = shape.getGeometry();

			// BOX
			if (geometry.getObjectType().equals(Constants.Box)) {

				VrmlBox box = (VrmlBox) geometry;
				BoxNode boxNode = new BoxNode();

				// box size
				boxNode.setSize(box.getX(), box.getY(), box.getZ());

				// box name
				if (box.getName() != null) {
					boxNode.setName(box.getName());
				}

				// add box as geometry node to shape
				shapeNode.addChildNode(boxNode);

				// SPHERE
			} else if (geometry.getObjectType().equals(Constants.Sphere)) {

				VrmlSphere sphere = (VrmlSphere) geometry;
				SphereNode sphereNode = new SphereNode();

				sphereNode.setRadius(sphere.getRadius());

				if (sphere.getName() != null) {
					sphereNode.setName(sphere.getName());
				}

				shapeNode.addChildNode(sphereNode);

				// CONE
			} else if (geometry.getObjectType().equals(Constants.Cone)) {

				VrmlCone cone = (VrmlCone) geometry;
				ConeNode coneNode = new ConeNode();

				coneNode.setBottomRadius(cone.getBottomRadius());
				coneNode.setHeight(cone.getHeight());
				coneNode.setBottom(cone.getBottom());
				coneNode.setSide(cone.getSide());

				if (cone.getName() != null) {
					coneNode.setName(cone.getName());
				}

				shapeNode.addChildNode(coneNode);

				// CYLINDER
			} else if (geometry.getObjectType().equals(Constants.Cylinder)) {

				VrmlCylinder cylinder = (VrmlCylinder) geometry;
				CylinderNode cylinderNode = new CylinderNode();

				cylinderNode.setRadius(cylinder.getRadius());
				cylinderNode.setHeight(cylinder.getHeight());
				cylinderNode.setBottom(cylinder.getBottom());
				cylinderNode.setSide(cylinder.getSide());
				cylinderNode.setTop(cylinder.getTop());

				if (cylinder.getName() != null) {
					cylinderNode.setName(cylinder.getName());
				}

				shapeNode.addChildNode(cylinderNode);
			}

			// TEXT

			// APPEARANCE //
			VrmlAppearance appearance = shape.getAppearence();

			if (appearance != null) {
				AppearanceNode appearanceNode = new AppearanceNode();

				// appearance name
				if (appearance.getName() != null) {
					appearanceNode.setName(appearance.getName());
				}

				// MATERIAL
				MaterialObject material = appearance.getMaterial();

				if (material != null) {
					MaterialNode materialNode = new MaterialNode();

					materialNode.setDiffuseColor(material.getDiffuseColor());
					materialNode.setAmbientIntensity(material
							.getAmbientIntensity());
					materialNode.setEmissiveColor(material.getEmissiveColor());
					materialNode.setSpecularColor(material.getSpecularColor());
					materialNode.setShininess(material.getShininess());
					materialNode.setTransparency(material.getTransparency());

					// material name
					if (material.getName() != null) {
						materialNode.setName(material.getName());
					}

					appearanceNode.addChildNode(materialNode);
				}

				// TEXTURE
				TextureObject texture = appearance.getTexture();

				if (texture != null) {

					// choose correct type of texture
					switch (texture.getTextureType()) {

					// IMAGE TEXTURE
					case Constants.ImageTexture: {
						ImageTextureNode textureNode = new ImageTextureNode();
						ImageTextureObject imageTexture = (ImageTextureObject) texture;

						textureNode.setName(texture.getName());
						textureNode.setRepeatS(imageTexture.isRepeatS());
						textureNode.setRepeatT(imageTexture.isRepeatT());

						// copy texture to the same directory /textures as the
						// model

						File oldTextureFile = new File(imageTexture
								.getTextureUrl().getFile());
						File modelFile = new File(fileName);
						File newTextureFile = new File(modelFile.getParent()
								+ File.separator + "textures" + File.separator
								+ oldTextureFile.getName());

						// create textures directory
						File theDir = new File(modelFile.getParent()
								+ File.separator + "textures");
						if (!theDir.exists()) {
							theDir.mkdir();
						}

						// create file with texture
						if (!newTextureFile.exists()) {
							try {
								newTextureFile.createNewFile();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}

						// copy texture
						try {
							InputStream in = new FileInputStream(oldTextureFile);
							OutputStream out = new FileOutputStream(
									newTextureFile);

							byte[] buf = new byte[1024];
							int len;
							while ((len = in.read(buf)) > 0) {
								out.write(buf, 0, len);
							}
							in.close();
							out.close();
						} catch (FileNotFoundException ex) {
							System.err.println(ex.getMessage());
						} catch (IOException e) {
							System.err.println(e.getMessage());
						}

						// ((ImageTextureNode)textureNode).setURLs(new String[]
						// {"textures" + File.separator +
						// oldTextureFile.getName()} );
						// tu som musel dat napevno taketo lomitko / lebo mi to
						// nechcelo importnut
						((ImageTextureNode) textureNode)
								.setURLs(new String[] { "textures/"
										+ oldTextureFile.getName() });

						appearanceNode.addChildNode(textureNode);
						break;
					}

					// MOVIE TEXTURE
					case Constants.MovieTexture:
						break;

					// PIXEL TEXTURE
					case Constants.PixelTexture: {
						PixelTextureNode pixelTextureNode = new PixelTextureNode();
						PixelTextureObject pixelTexture = (PixelTextureObject) texture;

						pixelTextureNode.setName(pixelTexture.getName());
						// pixelTextureNode.setImages("images");//pixelTexture.getTextureWidth()
						// + "" + pixelTexture.getTextureHeight() + "" +
						// pixelTexture.getTextureFormat());
						pixelTextureNode.setRepeatS(pixelTexture.isRepeatS());
						pixelTextureNode.setRepeatT(pixelTexture.isRepeatT());

						pixelTextureNode.setImages("2");

						// TODO pixel data export

						appearanceNode.addChildNode(pixelTextureNode);

						break;
					}
					}

				}

				// TEXTURE TRANSFORM
				TextureTransformObject textureTransform = appearance
						.getTextureTransform();

				if (textureTransform != null) {
					TextureTransformNode textureTransformNode = new TextureTransformNode();

					textureTransformNode.setScale(textureTransform.getScale());
					textureTransformNode.setRotation(textureTransform
							.getRotation());
					textureTransformNode
							.setCenter(textureTransform.getCenter());
					textureTransformNode.setTranslation(textureTransform
							.getTranslation());

					appearanceNode.addChildNode(textureTransformNode);
				}

				shapeNode.addChildNode(appearanceNode);
			}

			// /// FINAL SHAPE ADDING /////

			if (parentNode == null) {
				sg.addNode(shapeNode);
			} else {
				parentNode.addChildNode(shapeNode);
			}

			// VIEWPOINT
		} else if (obj.getObjectType().equals(Constants.View)) {

			ViewpointNode viewpointNode = new ViewpointNode();
			VrmlViewPoint viewpoint = (VrmlViewPoint) obj;
			
			//name
			if(viewpoint.getName() != null) {
				viewpointNode.setName(viewpoint.getName());
			}

			viewpointNode.setPosition(viewpoint.getPosition());
			viewpointNode.setOrientation(viewpoint.getOrientation());
			viewpointNode.setFieldOfView(viewpoint.getFOV());
			viewpointNode.setDescription(viewpoint.getDescription());
			viewpointNode.setJump(viewpoint.isJumpTrue());

			if (parentNode == null) {
				sg.addNode(viewpointNode);
			} else {
				parentNode.addChildNode(viewpointNode);
			}

		} else {
			System.err.println("unknown object type in exporting to vrml");
		}

	}

	/**
	 * Function imports VRML model from *.wrl file
	 */
	public void importFromFile() {
		fileName = showFileDialog(false);

		// actualize model
		this.activeModel = this.window.listener.getActivModel();

		if (fileName != null) {

			SceneGraph sg = new SceneGraph();

			sg.load(fileName);

			// explore node tree recursively
			Node node = sg.getNodes();
			while (node != null) {
				exploreNodeImport(node, null, null);
				node = node.next();
			}

			// no changes after open
			this.activeModel.resetModelChanged();
		}
	}

	/**
	 * Function recursively explore VRML node tree for import purpose
	 * 
	 * @param node
	 *            represents parent node
	 * @param parent
	 * 
	 */
	void exploreNodeImport(Node node, VrmlObject parent,
			DefaultMutableTreeNode treeParent) {

		// TRANSFORMATION
		if (node.getType().compareTo("Transform") == 0) {

			TransformNode transformNode = (TransformNode) node;
			VrmlTransform transform = new VrmlTransform();

			// rotation
			SFRotation rotation = transformNode.getRotationField();
			transform.setRotationX(rotation.getX());
			transform.setRotationY(rotation.getY());
			transform.setRotationZ(rotation.getZ());

			// translation
			float[] translation = new float[3];
			transformNode.getTranslation(translation);
			transform.setTranslation(translation);

			// scale
			float[] scale = new float[3];
			transformNode.getScale(scale);
			transform.setScale(scale);

			// scale orientation
			float[] scaleOrientation = new float[4];
			transformNode.getScaleOrientation(scaleOrientation);
			transform.setScaleOrientation(scaleOrientation);

			// center
			float[] center = new float[3];
			transformNode.getCenter(center);
			transform.setCenter(center);

			// name
			if (transformNode.getName() != null) {
				transform.setName(transformNode.getName());
			}

			// look at children
			int childrenCount = 0;
			Node childNode = node.getChildNodes();
			while (childNode != null) {
				if (childNode.getType().compareTo("Transform") != 0) {
					childrenCount++;
				}
				// exploreNodeImport(childNode, transform, null);
				childNode = childNode.next();
			}

			// if it has no children (shape children) add it to the tree
			if (childrenCount == 0) {
				if (treeParent == null) {
					DefaultMutableTreeNode root = activeModel.addTransformationToModel(transform,
							(DefaultMutableTreeNode) window.getTreeModel()
									.getModel().getRoot());

					// explore children
					Node childNode2 = node.getChildNodes();
					while (childNode2 != null) {
						exploreNodeImport(childNode2, transform, root);
						childNode2 = childNode2.next();
					}
				} else {
					DefaultMutableTreeNode root = activeModel.addTransformationToModel(transform, treeParent);

					// explore children
					Node childNode2 = node.getChildNodes();
					while (childNode2 != null) {
						exploreNodeImport(childNode2, transform, root);
						childNode2 = childNode2.next();
					}
				}
					
			// if it has shape children, first explore these children, than add it to the tree
			} else {
				
				// explore children
				Node childNode2 = node.getChildNodes();
				while (childNode2 != null) {
					exploreNodeImport(childNode2, transform, null);
					childNode2 = childNode2.next();
				}
				
				// 2 situations with tree parent a without
				if(parent == null) {
					activeModel.addComponentToModel(transform);
				} else {
					if(parent.getObjectType().equals(Constants.Transform)) {
						((VrmlTransform)parent).addChild(transform);
						window.addNodeAsChildToTree(transform, treeParent);
					}
				}
			}

//			// empty transformation
//			if (childrenCount == 0) {
//				if (parent == null) {
//					activeModel.addTransformationToModel(transform,
//							(DefaultMutableTreeNode) window.getTreeModel()
//									.getModel().getRoot());
//				} else {
//
//					// activeModel.addTransformationToModel(transform,
//					// (DefaultMutableTreeNode)parent);
//				}
//			} else {
//				activeModel.addComponentToModel(transform);
//			}

			// SHAPE
		} else if (node.getType().compareTo("Shape") == 0) {

			ShapeNode shapeNode = (ShapeNode) node;
			VrmlShape shape = new VrmlShape();

			// shape name
			if (shapeNode.getName() != null) {
				shape.setName(shapeNode.getName());
			}

			// /// GEOMETRY NODE /////
			GeometryNode geometryNode = shapeNode.getGeometryNode();

			if (geometryNode != null) {

				// BOX
				if (geometryNode.getType().compareTo("Box") == 0) {

					BoxNode boxNode = (BoxNode) geometryNode;

					VrmlBox box = new VrmlBox((int) boxNode.getX(),
							(int) boxNode.getY(), (int) boxNode.getZ());

					if (boxNode.getName() != null) {
						box.setName(boxNode.getName());
					}

					shape.setGeometry(box);

					// SPHERE
				} else if (geometryNode.getType().compareTo("Sphere") == 0) {

					SphereNode sphereNode = (SphereNode) geometryNode;

					VrmlSphere sphere = new VrmlSphere(sphereNode.getRadius());

					if (sphereNode.getName() != null) {
						sphere.setName(sphere.getName());
					}

					shape.setGeometry(sphere);

					// CONE
				} else if (geometryNode.getType().compareTo("Cone") == 0) {

					ConeNode coneNode = (ConeNode) geometryNode;

					VrmlCone cone = new VrmlCone(coneNode.getBottomRadius(),
							coneNode.getHeight(), coneNode.getSide(),
							coneNode.getBottom());

					if (coneNode.getName() != null) {
						cone.setName(coneNode.getName());
					}

					shape.setGeometry(cone);

					// CYLINDER
				} else if (geometryNode.getType().compareTo("Cylinder") == 0) {

					CylinderNode cylinderNode = (CylinderNode) geometryNode;

					VrmlCylinder cylinder = new VrmlCylinder(
							cylinderNode.getRadius(), cylinderNode.getHeight(),
							cylinderNode.getSide(), cylinderNode.getBottom(),
							cylinderNode.getTop());

					if (cylinderNode.getName() != null) {
						cylinder.setName(cylinderNode.getName());
					}

					shape.setGeometry(cylinder);
				}

				// TEXT

			}

			// /// APPEARANCE NODE /////
			AppearanceNode appearanceNode = shapeNode.getAppearanceNodes();

			if (appearanceNode != null) {
				VrmlAppearance appearance = new VrmlAppearance();

				// appearance name
				if (appearanceNode.getName() != null) {
					appearance.setName(appearanceNode.getName());
				}

				// MATERIAL
				MaterialNode materialNode = appearanceNode.getMaterialNodes();

				if (materialNode != null) {

					float[] diffuseColor = new float[4];
					float[] emissiveColor = new float[4];
					float[] specularColor = new float[4];

					materialNode.getDiffuseColor(diffuseColor);
					materialNode.getEmissiveColor(emissiveColor);
					materialNode.getSpecularColor(specularColor);

					MaterialObject material = new MaterialObject(diffuseColor,
							materialNode.getAmbientIntensity(), emissiveColor,
							specularColor, materialNode.getShininess(),
							materialNode.getTransparency());

					if (appearanceNode.getName() != null) {
						appearance.setName(appearanceNode.getName());
					}

					appearance.setMaterial(material);

				} else {

					// create empty material object
					appearance.setMaterial(new MaterialObject());
				}

				// TEXTURE
				TextureNode textureNode = appearanceNode.getTextureNode();

				if (textureNode != null) {

					if (textureNode.isImageTextureNode()) {
						ImageTextureObject texture = new ImageTextureObject();
						ImageTextureNode imageNode = (ImageTextureNode) textureNode;

						texture.setRepeatS(imageNode.getRepeatS());
						texture.setRepeatT(imageNode.getRepeatT());

						// full texture path
						File path = new File(fileName);
						String fullPath = path.getParent() + File.separator
								+ imageNode.getURL(0);

						try {
							texture.setTextureUrl(new URL("file", "", fullPath));
						} catch (Exception e) {
							System.err
									.println("Bad URL in image texture in importing vrml file "
											+ e.getMessage());
						}

						texture.setName(imageNode.getName());

						// appearance.setTexture(texture);
						appearance.setImageTexture(texture);
					}

					if (textureNode.isMovieTextureNode()) {
					}

					if (textureNode.isPixelTextureNode()) {
					}

				} else {

					// create empty texture
					// appearance.setTexture(new TextureObject());

				}

				// TEXTURE TRANSFORM
				TextureTransformNode textureTransformNode = appearanceNode
						.getTextureTransformNodes();

				if (textureTransformNode != null) {

					float[] scale = new float[2];
					float[] center = new float[2];
					float[] translation = new float[2];

					textureTransformNode.getScale(scale);
					textureTransformNode.getCenter(center);
					textureTransformNode.getTranslation(translation);

					TextureTransformObject textureTransform = new TextureTransformObject(
							scale, textureTransformNode.getRotation(), center,
							translation);

					appearance.setTextureTransform(textureTransform);

				} else {

					// create empty texture transform
					appearance
							.setTextureTransform(new TextureTransformObject());

				}

				// add apearance to shape
				shape.setAppearence(appearance);

			} else {

				// create empty default appearance
				VrmlAppearance appearance = new VrmlAppearance();
				appearance.setMaterial(new MaterialObject());
				appearance.setTexture(new TextureObject());
				appearance.setTextureTransform(new TextureTransformObject());
				shape.setAppearence(appearance);

			}

			// add shape to transform object
			if (parent != null
					&& parent.getObjectType().equals(Constants.Transform)) {
				VrmlTransform transform = (VrmlTransform) parent;
				transform.addChild(shape);
			} else {
				System.err
						.println("invalid shape parent in importing from vrml: "
								+ parent.getObjectType());
			}

			// BACKGROUND
		} else if (node.getType().compareTo("Background") == 0) {

			BackgroundNode backgroundNode = (BackgroundNode) node;
			VrmlBackground background = new VrmlBackground();

			// sky angles
			MFFloat skyAngles = backgroundNode.getSkyAngleField();
			background.setSkyAngles(skyAngles.getValues());

			// sky colors
			MFColor skyColors = backgroundNode.getSkyColorField();
			background.setSkyColors(skyColors.getValues());

			// ground angles
			MFFloat groundAngles = backgroundNode.getGroundAngleField();
			background.setGroundAngles(groundAngles.getValues());

			// ground colors
			MFColor groundColors = backgroundNode.getGroundColorField();
			background.setGroundColors(groundColors.getValues());

			activeModel.setModelBackground(background);

			// VIEWPOINT
		} else if (node.getType().compareTo("Viewpoint") == 0) {

			ViewpointNode viewpointNode = (ViewpointNode) node;

			float[] position = new float[3];
			float[] orientation = new float[4];

			viewpointNode.getPosition(position);
			viewpointNode.getOrientation(orientation);

			VrmlViewPoint viewpoint = new VrmlViewPoint(position, orientation,
					viewpointNode.getFieldOfView(), viewpointNode.getJump(),
					viewpointNode.getDescription(), viewpointNode.getName());
			
			// name
			if(viewpointNode.getName() != null) {
				viewpoint.setName(viewpointNode.getName());
			}

			ArrayList <VrmlViewPoint> viewpoints = window.viewpointStorage.getViewpoints();
			viewpoints.add(viewpoint);
			activeModel.addViewPointToModel(viewpoint);

		} else {
			System.err.println("unknown object type in importing from vrml");
		}

	}

	/**
	 * Method shows dialog for opening or saving file
	 * 
	 * @param save
	 *            if true, than save dialog is opened, else open dialog is
	 *            opened
	 */
	private String showFileDialog(boolean save) {

		String wd;
		if (lastDirectory != null) {
			wd = lastDirectory;
		} else {
			wd = System.getProperty("user.home");
		}
		final JFileChooser fc = new JFileChooser(wd);

		// action button type
		if (save) {
			fc.setApproveButtonText("Save");
		} else {
			fc.setApproveButtonText("Open");
		}

		// accept only VRML files (*.wrl or *.WRL)
		fc.setFileFilter(new FileFilter() {

			@Override
			public String getDescription() {
				return "*.wrl (VRML files)";
			}

			@Override
			public boolean accept(File arg0) {
				if (arg0.isDirectory()) {
					return true;
				}
				String[] fileNameArray = arg0.getAbsolutePath().split("[.]");
				if (fileNameArray.length > 1
						&& (fileNameArray[fileNameArray.length - 1]
								.compareTo("wrl") == 0 || fileNameArray[fileNameArray.length - 1]
								.compareTo("WRL") == 0)) {
					return true;
				} else {
					return false;
				}
			}
		});

		if (save) {
			fc.setDialogTitle("Save");
			fc.setSelectedFile(new File("model.wrl"));
		} else {
			fc.setDialogTitle("Open");
		}

		int returnVal = fc.showOpenDialog(null);

		if (returnVal == JFileChooser.APPROVE_OPTION) {
			File file = fc.getSelectedFile();

			// save selected directory
			lastDirectory = file.getAbsolutePath();

			// file replacing case
			if (file.exists() && save) {
				String msg = "The file " + file.getName()
						+ " already exists!\nDo you want to replace it?";
				String title = fc.getDialogTitle();
				int option = JOptionPane.showConfirmDialog(fc, msg, title,
						JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
				if (option == JOptionPane.NO_OPTION) {
					// reopen save dialog
					showFileDialog(true);
					return null;
				}

			}

			// check for file extension, if it isn't .wrl change it
			String fileName = file.getAbsolutePath();
			String[] fileNameArray = fileName.split("[.]");
			if (fileNameArray.length < 2
					|| fileNameArray[fileNameArray.length - 1].compareTo("wrl") != 0) {
				fileName += ".wrl";
			}

			return fileName;
		} else {
			return null;
		}

	}
}
